home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / edit / mg2a_src.zip / PARAGRAP.C < prev    next >
C/C++ Source or Header  |  1988-08-23  |  8KB  |  273 lines

  1. /*
  2.  * Code for dealing with paragraphs and filling. Adapted from MicroEMACS 3.6
  3.  * and GNU-ified by mwm@ucbvax.     Several bug fixes by blarson@usc-oberon.
  4.  */
  5. #include "def.h"
  6.  
  7. static int    fillcol = 70 ;
  8. #define MAXWORD 256
  9.  
  10. /*
  11.  * go back to the begining of the current paragraph
  12.  * here we look for a <NL><NL> or <NL><TAB> or <NL><SPACE>
  13.  * combination to delimit the begining of a paragraph
  14.  */
  15. /*ARGSUSED*/
  16. gotobop(f, n)
  17. {
  18.     if (n < 0)    /* the other way...*/
  19.         return gotoeop(f, -n);
  20.  
  21.     while (n-- > 0) {    /* for each one asked for */
  22.  
  23.         /* first scan back until we are in a word */
  24.         
  25.         while (backchar(FFRAND, 1) && !inword()) {}
  26.         curwp->w_doto = 0;    /* and go to the B-O-Line */
  27.  
  28.         /* and scan back until we hit a <NL><SP> <NL><TAB> or <NL><NL> */
  29.         while (lback(curwp->w_dotp) != curbp->b_linep)
  30.             if (llength(lback(curwp->w_dotp))
  31.                 && lgetc(curwp->w_dotp,0) != ' '
  32.                 && lgetc(curwp->w_dotp,0) != '\t')
  33.                 curwp->w_dotp = lback(curwp->w_dotp);
  34.             else
  35.                 break;
  36.     }
  37.     curwp->w_flag |= WFMOVE;    /* force screen update */
  38.     return TRUE;
  39. }
  40.  
  41. /*
  42.  * go forword to the end of the current paragraph
  43.  * here we look for a <NL><NL> or <NL><TAB> or <NL><SPACE>
  44.  * combination to delimit the begining of a paragraph
  45.  */
  46. /*ARGSUSED*/
  47. gotoeop(f, n)
  48. {
  49.     if (n < 0)    /* the other way...*/
  50.         return gotobop(f, -n);
  51.  
  52.     while (n-- > 0) {    /* for each one asked for */
  53.  
  54.         /* Find the first word on/after the current line */
  55.         curwp->w_doto = 0;
  56.         while(forwchar(FFRAND, 1) && !inword()) {}
  57.         curwp->w_doto = 0;
  58.         curwp->w_dotp = lforw(curwp->w_dotp);
  59.         /* and scan forword until we hit a <NL><SP> or ... */
  60.         while (curwp->w_dotp != curbp->b_linep) {
  61.             if (llength(curwp->w_dotp)
  62.                 && lgetc(curwp->w_dotp,0) != ' '
  63.                 && lgetc(curwp->w_dotp,0) != '\t')
  64.                 curwp->w_dotp = lforw(curwp->w_dotp);
  65.             else
  66.                 break;
  67.         }
  68.         if(curwp->w_dotp == curbp->b_linep) {
  69.             /* beond end of buffer, cleanup time */
  70.             curwp->w_dotp = lback(curwp->w_dotp);
  71.             curwp->w_doto = llength(curwp->w_dotp);
  72.             break;            
  73.         }
  74.     }
  75.     curwp->w_flag |= WFMOVE;    /* force screen update */
  76.     return TRUE;
  77. }
  78.  
  79. /*
  80.  * Fill the current paragraph according to the current
  81.  * fill column
  82.  */
  83. /*ARGSUSED*/
  84. fillpara(f, n)
  85. {
  86.     register int    c;        /* current char durring scan    */
  87.     register int    wordlen;    /* length of current word    */
  88.     register int    clength;    /* position on line during fill */
  89.     register int    i;        /* index during word copy    */
  90.     register int    eopflag;    /* Are we at the End-Of-Paragraph? */
  91.     int        firstflag;    /* first word? (needs no space) */
  92.     int        newlength;    /* tentative new line length    */
  93.     int        eolflag;    /* was at end of line        */
  94.     LINE        *eopline;    /* pointer to line just past EOP */
  95.     char wbuf[MAXWORD];        /* buffer for current word    */
  96.  
  97.     /* record the pointer to the line just past the EOP */
  98.     (VOID) gotoeop(FFRAND, 1);
  99.     if(curwp->w_doto != 0)    {
  100.         /* paragraph ends at end of buffer */
  101.         (VOID) lnewline();
  102.         eopline = lforw(curwp->w_dotp);
  103.     } else    eopline = curwp->w_dotp;
  104.  
  105.     /* and back top the begining of the paragraph */
  106.     (VOID) gotobop(FFRAND, 1);
  107.  
  108.     /* initialize various info */
  109.     while (!inword() && forwchar(FFRAND, 1)) {}
  110.     clength = curwp->w_doto;
  111.     wordlen = 0;
  112.  
  113.     /* scan through lines, filling words */
  114.     firstflag = TRUE;
  115.     eopflag = FALSE;
  116.     while (!eopflag) {
  117.         /* get the next character in the paragraph */
  118.         if (eolflag=(curwp->w_doto == llength(curwp->w_dotp))) {
  119.             c = ' ';
  120.             if (lforw(curwp->w_dotp) == eopline)
  121.                 eopflag = TRUE;
  122.         } else
  123.             c = lgetc(curwp->w_dotp, curwp->w_doto);
  124.  
  125.         /* and then delete it */
  126.         if (ldelete((RSIZE) 1, KNONE) == FALSE && !eopflag)
  127.             return FALSE;
  128.  
  129.         /* if not a separator, just add it in */
  130.         if (c != ' ' && c != '\t') {
  131.             if (wordlen < MAXWORD - 1)
  132.                 wbuf[wordlen++] = c;
  133.             else {
  134.                 /* You loose chars beyond MAXWORD if the word
  135.                  * is to long. I'm to lazy to fix it now; it
  136.                  * just silently truncated the word before, so
  137.                  * I get to feel smug.
  138.                  */
  139.                 ewprintf("Word too long!");
  140.             }
  141.         } else if (wordlen) {
  142.             /* calculate tenatitive new length with word added */
  143.             newlength = clength + 1 + wordlen;
  144.             /* if at end of line or at doublespace and previous
  145.              * character was one of '.','?','!' doublespace here.
  146.              */
  147.             if((eolflag || curwp->w_doto==llength(curwp->w_dotp)
  148.                 || (c=lgetc(curwp->w_dotp,curwp->w_doto))==' '
  149.                 || c=='\t')
  150.               && ISEOSP(wbuf[wordlen-1])
  151.               && wordlen<MAXWORD-1)
  152.                 wbuf[wordlen++] = ' ';
  153.             /* at a word break with a word waiting */
  154.             if (newlength <= fillcol) {
  155.                 /* add word to current line */
  156.                 if (!firstflag) {
  157.                     (VOID) linsert(1, ' ');
  158.                     ++clength;
  159.                 }
  160.                 firstflag = FALSE;
  161.             } else {
  162.                 if(curwp->w_doto > 0 &&
  163.                     lgetc(curwp->w_dotp,curwp->w_doto-1)==' ') {
  164.                     curwp->w_doto -= 1;
  165.                     (VOID) ldelete((RSIZE) 1, KNONE);
  166.                 }
  167.                 /* start a new line */
  168.                 (VOID) lnewline();
  169.                 clength = 0;
  170.             }
  171.  
  172.             /* and add the word in in either case */
  173.             for (i=0; i<wordlen; i++) {
  174.                 (VOID) linsert(1, wbuf[i]);
  175.                 ++clength;
  176.             }
  177.             wordlen = 0;
  178.         }
  179.     }
  180.     /* and add a last newline for the end of our new paragraph */
  181.     (VOID) lnewline();
  182.     /* we realy should wind up where we started, (which is hard to keep
  183.      * track of) but I think the end of the last line is better than the
  184.      * begining of the blank line.     */
  185.     (VOID) backchar(FFRAND, 1);
  186.     return TRUE;
  187. }
  188.  
  189. /* delete n paragraphs starting with the current one */
  190. /*ARGSUSED*/
  191. killpara(f, n)
  192. {
  193.     register int status;    /* returned status of functions */
  194.  
  195.     while (n--) {        /* for each paragraph to delete */
  196.  
  197.         /* mark out the end and begining of the para to delete */
  198.         (VOID) gotoeop(FFRAND, 1);
  199.  
  200.         /* set the mark here */
  201.         curwp->w_markp = curwp->w_dotp;
  202.         curwp->w_marko = curwp->w_doto;
  203.  
  204.         /* go to the begining of the paragraph */
  205.         (VOID) gotobop(FFRAND, 1);
  206.         curwp->w_doto = 0;    /* force us to the begining of line */
  207.  
  208.         /* and delete it */
  209.         if ((status = killregion(FFRAND, 1)) != TRUE)
  210.             return status;
  211.  
  212.         /* and clean up the 2 extra lines */
  213.         (VOID) ldelete((RSIZE) 1, KFORW);
  214.     }
  215.     return TRUE;
  216. }
  217.  
  218. /*
  219.  * check to see if we're past fillcol, and if so,
  220.  * justify this line. As a last step, justify the line.
  221.  */
  222. /*ARGSUSED*/
  223. fillword(f, n)
  224. {
  225.     register char    c;
  226.     register int    col, i, nce;
  227.  
  228.     for (i = col = 0; col <= fillcol; ++i, ++col) {
  229.         if (i == curwp->w_doto) return selfinsert(f, n) ;
  230.         c = lgetc(curwp->w_dotp, i);
  231.         if (c == '\t'
  232. #ifdef    NOTAB
  233.             && !(curbp->b_flag & BFNOTAB)
  234. #endif
  235.             ) col |= 0x07;
  236.         else if (ISCTRL(c) != FALSE) ++col;
  237.     }
  238.     if (curwp->w_doto != llength(curwp->w_dotp)) {
  239.         (VOID) selfinsert(f, n);
  240.         nce = llength(curwp->w_dotp) - curwp->w_doto;
  241.     } else nce = 0;
  242.     curwp->w_doto = i;
  243.  
  244.     if ((c = lgetc(curwp->w_dotp, curwp->w_doto)) != ' ' && c != '\t')
  245.         do {
  246.             (VOID) backchar(FFRAND, 1);
  247.         } while ((c = lgetc(curwp->w_dotp, curwp->w_doto)) != ' '
  248.               && c != '\t' && curwp->w_doto > 0);
  249.  
  250.     if (curwp->w_doto == 0)
  251.         do {
  252.             (VOID) forwchar(FFRAND, 1);
  253.         } while ((c = lgetc(curwp->w_dotp, curwp->w_doto)) != ' '
  254.               && c != '\t' && curwp->w_doto < llength(curwp->w_dotp));
  255.  
  256.     (VOID) delwhite(FFRAND, 1);
  257.     (VOID) lnewline();
  258.     i = llength(curwp->w_dotp) - nce;
  259.     curwp->w_doto = i>0 ? i : 0;
  260.     curwp->w_flag |= WFMOVE;
  261.     if (nce == 0 && curwp->w_doto != 0) return fillword(f, n);
  262.     return TRUE;
  263. }
  264.  
  265. /* Set fill column to n. */
  266. setfillcol(f, n) {
  267.     extern int    getcolpos() ;
  268.  
  269.     fillcol = ((f & FFARG) ? n : getcolpos());
  270.     ewprintf("Fill column set to %d", fillcol);
  271.     return TRUE;
  272. }
  273.